package com.company.beauty.common.utils;

import cn.hutool.core.lang.UUID;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpUtil;
import com.company.beauty.common.config.RestTemplateConfiguration;
import com.company.beauty.common.retry.RetryRequestHandler;
import com.company.beauty.common.retry.RetryRequestHandlerFactory;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

/**
 * <p>通知处理类</p >
 *
 * @author youyoukele
 * @version 1.0
 * @date 2024/4/12 09:49
 */
@Slf4j
public class ServiceNotifyUtil {

    private static final RestTemplate REST_TEMPLATE = SpringUtil.getBean(RestTemplateConfiguration.BALANCED_REST_TEMPLATE_BEAN, RestTemplate.class);
    private static final RetryRequestHandler RETRY_REQUEST_HANDLER = RetryRequestHandlerFactory.getRetryRequestHandler();

    /**
     * callback
     * <p>
     * 仅支持 application/json, post 请求
     *
     * @param url         请求链接
     *                    内网服务调用 e.g http://xxxx-service/xxxxxx
     *                    外网https调用 e.g https://xxxxxxx/xxxx
     * @param requestBody json格式请求参数 e.g {"id": 123}
     * @return {@link Result}
     */
    public static Result callback(String url, String requestBody) {
        return callback(url, requestBody, Boolean.TRUE);
    }

    /**
     * callback
     * <p>
     * 仅支持 application/json, post 请求
     *
     * @param url         请求链接
     *                    内网服务调用 e.g http://xxxx-service/xxxxxx
     *                    外网https调用 e.g https://xxxxxxx/xxxx
     * @param requestBody json格式请求参数 e.g {"id": 123}
     * @param switchRetry 是否开启重试机制
     * @return {@link Result}
     */
    public static Result callback(String url, String requestBody, boolean switchRetry) {
        try {
            // 如果是 https 请求，则认为走外网调用，否则走内网服务发现调用
            boolean isExternalNetwork = url.startsWith("https");
            if (isExternalNetwork) {
                return Result.success(HttpUtil.post(url, requestBody));
            }
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<String> response = REST_TEMPLATE.exchange(url, HttpMethod.POST, entity, String.class);
            log.info("callback response:{}", response);
            return Result.success(response.getBody());
        } catch (Exception e) {
            log.error("callback exception, url:{}, requestBody:{}", url, requestBody, e);
            if (switchRetry) {
                // 调用失败，记录重试记录
                RETRY_REQUEST_HANDLER.addRetry(UUID.randomUUID().toString(Boolean.TRUE), url, requestBody);
            }
            return Result.fail();
        }
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static final class Result {
        /**
         * 结果
         */
        private boolean result;
        /**
         * 报文体
         */
        private String body;

        public static Result success(String body) {
            return new Result(Boolean.TRUE, body);
        }

        public static Result fail() {
            return new Result(Boolean.FALSE, null);
        }
    }

}
